import pygame
from pygame import Rect
from animated_sprite import FramesSet, PlayMode, AnimatedSprite
from atlas_texture import AtlasTexture
from timer import Timer
from camera import Camera
from area import Area
from collision_shape import RectCollisionShape, CircleCollisionShape



pygame.init()

font = pygame.font.SysFont('SimHei', 22)
def show_top_text(surface: pygame.Surface, text: str, font: pygame.font.Font, color: pygame.Color, pos: pygame.Vector2):
    surface.blit(font.render(text, True, color), pos)

bg = pygame.image.load(r"./test/bg.jpg")

canvas = pygame.display.set_mode((1280, 720), pygame.SHOWN, vsync=1)
display_surface = pygame.Surface((3000, 3000))
camera = Camera(display_surface, pygame.Vector2(320, 180)).set_zoom(pygame.Vector2(0.5, 0.5))
clock = pygame.time.Clock()
delta = 0
clear_color = (57, 57, 57)

group = pygame.sprite.Group()

path = r"./test/test.png"
texture = AtlasTexture(path)
frame1 = texture.set_region(Rect(0, 64, 32, 32)).surface()
frame2 = texture.set_region(Rect(32, 64, 32, 32)).surface()
frame3 = texture.set_region(Rect(64, 64, 32, 32)).surface()
frame4 = texture.set_region(Rect(96, 64, 32, 32)).surface()

frames_set = FramesSet([frame1, frame2, frame3, frame4], "test", 6)
frames_set.play_mode = PlayMode.REPEAT
sprite = AnimatedSprite(group)
sprite.rect.topleft = (50, 50)
sprite.add_frames_set(frames_set)
# sprite.add_frames_set_from_dict({"test": frames_set})
sprite.play("test")

setattr(sprite, "collision_rect", pygame.Rect(0, 0, 24, 24))

def draw_rect(surface: pygame.Surface):
    surface.blit(sprite.image, sprite.rect)
    pygame.draw.rect(surface, (0, 255, 0), sprite.rect, 2)
    sprite.collision_rect.topleft = (sprite.rect.x + 4, sprite.rect.y + 4)
    pygame.draw.rect(surface, (255, 0, 0), sprite.collision_rect, 2)

sprite.draw = draw_rect

direction = pygame.Vector2()
def control_sprite() -> None:
    global direction, delta
    keys = pygame.key.get_pressed()
    if keys[pygame.K_d]:
        direction.x = 1
    elif keys[pygame.K_a]:
        direction.x = -1
    else:
        direction.x = 0

    if keys[pygame.K_s]:
        direction.y = 1
    elif keys[pygame.K_w]:
        direction.y = -1
    else:
        direction.y = 0

    if direction.is_normalized():
        direction = direction.normalize()
    sprite.rect.topleft += direction * delta * 40

camera.attach_sprite(sprite)


rect_area = Area(RectCollisionShape(Rect(200, 50, 100, 100))).show_shape(True).set_shape_color((255, 0, 0, 80))

circle_area = Area(CircleCollisionShape(pygame.Vector2(200, 300), 50)).show_shape(True).set_shape_color((0, 0, 255, 80))


def on_area_sprite_entered(sprite):
    print("sprite entered,", sprite)

def on_area_sprite_exited(sprite):
    print("sprite exited,", sprite)

rect_area.sprite_entered_signal.connect(on_area_sprite_entered)
rect_area.sprite_exited_signal.connect(on_area_sprite_exited)

circle_area.sprite_entered_signal.connect(on_area_sprite_entered)
circle_area.sprite_exited_signal.connect(on_area_sprite_exited)


while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            exit()

    # update
    sprite.update()
    control_sprite()
    camera.update()

    rect_area.update([sprite])
    circle_area.update([sprite])

    # draw
    display_surface.fill(clear_color)
    display_surface.blit(bg, (0, 0))
    sprite.draw(display_surface)
    rect_area.draw(display_surface)
    circle_area.draw(display_surface)
    camera.draw(canvas)


    show_top_text(canvas, f"player pos: {sprite.rect.topleft}", font, pygame.Color(255, 255, 255), pygame.Vector2(0, 0))
    show_top_text(canvas, f"camera pos: {camera.get_pos()}", font, pygame.Color(255, 255, 255), pygame.Vector2(0, 30))
    show_top_text(canvas, f"player rect: {sprite.rect}", font, (255, 0, 0), (0, 60))
    show_top_text(canvas, f"camera limit region: {camera.get_limit_region()}", font, (255, 0, 0), (0, 90))
    show_top_text(canvas, f"fps: {int(clock.get_fps())}", font, (255, 255, 0), (0, 690))

    pygame.display.flip()

    delta = clock.tick(60) / 1000